#include <cstdlib>
#include <cstring>
#include <iostream>
#include "quickjs.h"

static JSValue promise_handler(JSContext *ctx, JSValueConst this_val, int argc,
                               JSValueConst *argv) {
  JSValue promise = JS_NewPromiseCapability(ctx, NULL);
  JSValue result = JS_Call(ctx, argv[0], JS_UNDEFINED, 0, NULL);

  if (JS_IsException(result)) {
    JS_FreeValue(ctx, promise);
    return JS_EXCEPTION;
  }
  JS_FreeValue(ctx, result);
  return promise;
}

int main(int argc, char **argv) {
  JSRuntime *rt;
  JSContext *ctx;
  JSValue global_obj, func, ret;

  rt = JS_NewRuntime();
  ctx = JS_NewContext(rt);

  global_obj = JS_GetGlobalObject(ctx);

  func = JS_NewCFunction(ctx, promise_handler, "promise_handler", 1);
  JS_SetPropertyStr(ctx, global_obj, "promiseHandler", func);

  const char *script = "promiseHandler(function() {\n "
                       " return new Promise((resolve, reject) => {\n"
                       "   setTimeout(() => resolve('hello, world!), 1000);\n"
                       " });\n"
                       "}).then(console.log);\n";
  ret = JS_Eval(ctx, script, strlen(script), "script.js", 0);
  if (JS_IsException(ret)) {
    JS_FreeValue(ctx, global_obj);
    JS_FreeContext(ctx);
    JS_FreeRuntime(rt);
    return 1;
  }

  JS_FreeValue(ctx, ret);
  JS_FreeValue(ctx, global_obj);
  JS_FreeContext(ctx);
  JS_FreeRuntime(rt);

  return 0;
}